﻿using System;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Normalization
{
    /// <summary>
    /// 内部归一化器接口
    /// </summary>
    public interface IInnerNormalizer<TSource, TResult>
         where TSource : struct, IComparable<TSource>
         where TResult : struct, IComparable<TResult>
    {
        /// <summary>
        /// 获取归一化选项参数
        /// </summary>
        NormalizerOptions Options { get; }

        /// <summary>
        /// 重置归一化器,恢复至构造初始状态
        /// </summary>
        void Reset();

        /// <summary>
        /// 计算归一化系数
        /// </summary>
        /// <param name="minValue">数据源数据中的最小值</param>
        /// <param name="maxValue">数据源数据中的最大值</param>
        /// <param name="inputOffset">输入数据偏移量</param>
        /// <returns>归一化系数</returns>
        double CaculateNormalizeFactor(double minValue, double maxValue, out double inputOffset);

        /// <summary>
        /// 执行单个值归一化
        /// </summary>
        /// <param name="source">归一化原始数据</param>
        /// <param name="factor">归一化系数,当为映射时此参数不使用,填任意值</param>
        /// <param name="inputOffset">输入数据偏移量,当为映射时此参数不使用,填任意值</param>
        /// <returns>单个值归一化结果</returns>
        TResult Excute(TSource source, double factor, double inputOffset);

        /// <summary>
        /// 执行归一化,当原始数据长度与结果数据不一致时,取较小值为长度
        /// </summary>
        /// <param name="source">归一化原始数据</param>
        /// <param name="dest">归一化结果数据</param>
        void Excute(Span<TSource> source, Span<TResult> dest);

        /// <summary>
        /// 执行归一化,当原始数据长度与结果数据不一致时,取较小值为长度
        /// </summary>
        /// <param name="source">归一化原始数据</param>
        /// <param name="dest">归一化结果数据</param>
        void Excute(SpanZ<TSource> source, SpanZ<TResult> dest);

    }
}
